﻿#include "widget.h"
#include "ui_widget.h"
#include <Windows.h>
#include <QPainter>
#include <QMouseEvent>

#include <QAxObject>
#include <QUuid>
#include <QClipboard>
#include <QCryptographicHash>

#include <QDebug>
#include <QBuffer>
#include <QFile>
#include <QSettings>
#include <QMessageBox>

#define COLORCustumYellow "#fdfdca"
#define COLORCustumBlue "#d7f2fa"
#define COLORCustumGreen "#d0fdca"
#define COLORCustumPurple "#dcd7fe"
#define COLORCustumPink "#f4cff4"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    m_currentBGColor = COLORCustumPurple;

    setWindowFlags(Qt::FramelessWindowHint);
    setAttribute(Qt::WA_TranslucentBackground);
    setAttribute(Qt::WA_DeleteOnClose);

    ui->btnpin->setCheckable(true);
    ui->btnpin->setChecked(false);
    ui->btnRegist->setEnabled(false);
    ui->data_end->setDate(QDateTime::currentDateTime().date());
    ui->cmboxApp->lineEdit()->setPlaceholderText(QStringLiteral("输入要注册的软件名称"));

    connect(ui->data_end,&QDateEdit::dateTimeChanged,[=](const QDateTime & datetime){
        QDateTime currentdate = QDateTime::currentDateTime();
        int days = currentdate.daysTo(datetime);
        ui->lbldays->setText(QString::number(days));
    });

    QDate _date = ui->data_end->date();
    if(_date.month()==12){
        _date.setDate(_date.year() + 1 , 1 , _date.day() );
    }else
        _date.setDate(QDateTime::currentDateTime().date().year(),QDateTime::currentDateTime().date().month() + 1,_date.day());
    ui->data_end->setDate(_date);

    QSettings setFeeder("HKEY_CURRENT_USER\\Software\\YanboOrg",QSettings::NativeFormat);
    foreach(QString str,setFeeder.childGroups()){
         ui->cmboxApp->addItem(str,str);
    }

    paracode();

    connect(ui->cmboxApp->lineEdit(),&QLineEdit::textEdited,[=](const QString & text){
        ui->cmboxApp->addItem(text,text);
    });
    connect(ui->btnRegist,&QToolButton::clicked,[=]{
        QString appname(ui->cmboxApp->currentText());
        qDebug()<<endl<<endl<<appname;
        if(appname.isEmpty()){
            QMessageBox::about(0,"",QStringLiteral("请输入/选择要激活的软件."));
            return;
        }
        if(RegisterFeeder(appname))
            QMessageBox::about(0,"",QStringLiteral("软件注册成功."));
        else
            QMessageBox::about(0,"",QStringLiteral("注册失败."));

    });
    connect(ui->btnGenal,&QToolButton::clicked,[=]{
        if(!GetCustCodeOfFeeder().isEmpty()){
            QMessageBox::about(0,"",QStringLiteral("激活码已生成并复制到剪贴板，点击注册进行软件注册!"));
            if(!ui->btnRegist->isEnabled())
                ui->btnRegist->setEnabled(true);
        }else{
            QMessageBox::about(0,"",QStringLiteral("激活码生成失败，请联系管理员."));
            ui->btnRegist->setEnabled(false);
        }
    });

    connect(ui->btnclose,&QToolButton::clicked,[=]{
        qApp->quit();
    });
    connect(ui->btnmin,&QToolButton::clicked,[=]{
        this->showMinimized();
    });
    connect(ui->btnpin,&QToolButton::clicked,[=]{
        Qt::WindowFlags flags = windowFlags();
        if(ui->btnpin->isChecked()){
#ifdef Q_OS_WIN
            SetWindowPos((HWND)(this->winId()), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
#else
            this->setWindowFlags(flags | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint);
#endif
        }
        else
        {
#ifdef Q_OS_WIN
            SetWindowPos((HWND)(this->winId()), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
#else
            this->setWindowFlags(flags ^ (Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint));
#endif
        }
    });
}

Widget::~Widget()
{
    delete ui;
}

void Widget::mousePressEvent(QMouseEvent *event){
    m_windowPos = event->globalPos() - pos();
}

void Widget::mouseMoveEvent(QMouseEvent *event){
    move(event->globalPos() - m_windowPos);
}

bool Widget::RegisterFeeder(QString appname){
    QSettings reg(QString("HKEY_CURRENT_USER\\Software\\Active\\%1").arg(appname),QSettings::NativeFormat);
    reg.setValue("activeCode",m_custRegistCode);

    QByteArray plaintext;
    QBuffer buffer(&plaintext);
    buffer.open(QIODevice::WriteOnly);
    QDataStream s(&buffer);
    s.setVersion(QDataStream::Qt_5_2);
    s << ui->lbldays->text(); //stream in a string
    s << QDateTime::currentDateTime().toString("yyyyMMdd");
    s << ui->lineEditUsr->text(); //stream in a string
    reg.setValue("activeInfo",plaintext);
    buffer.close();
    return true;
}

void Widget::paracode()
{
    QSettings reg(QString("HKEY_CURRENT_USER\\Software\\Active\\%1").arg(ui->cmboxApp->currentText()),QSettings::NativeFormat);
    QString code = reg.value("activeCode",m_custRegistCode).toString();

    QByteArray bytearrayCode = QByteArray::fromHex(code.toLocal8Bit());

    QByteArray sha1(QCryptographicHash::hash(bytearrayCode,QCryptographicHash::Sha1));
    qDebug()<<sha1;

    //code:da8c1cee21cce55c50d00aed76a8571f3cc8fc41

//    QString cusinfo(QString((username.isEmpty()?"@@@ihepweiqunApplication":"@@@ihepweiqunApplication"+username) + "@@@%1@@@%2").arg(
//                        QDateTime::currentDateTime().toString("yyyyMMdd"),
//                        QString::number(validays)));
//    QString originalStr120= QStringLiteral("@@@")+machineCode+cusinfo;
//    QCryptographicHash sha1(QCryptographicHash::Sha1);
//    QByteArray datagram(originalStr120.toLatin1());
//    const char* tempConstChar = datagram.data();
//    sha1.addData(tempConstChar);
}

QString Widget::GetCustCodeOfFeeder()
{
    QString code("");
    QString maccode(getWMIHWInfo(2));
    code.append(maccode);

    int days = ui->lbldays->text().toInt();

    //格式：机器码    使用天数    激活日期    用户名
    code = calActiveCode(code,days,ui->lineEditUsr->text());

    qDebug()<<code<<days;

    //if success.
    ui->textEdit->setPlainText(QStringLiteral("  注册码为：") + code + QStringLiteral("\n  机器码为：") + maccode
                               );
    return code;
}

QString Widget::calActiveCode(QString machineCode,int validays,QString username){
    QString cusinfo(QString((username.isEmpty()?"@@@ihepweiqunApplication":"@@@ihepweiqunApplication"+username) + "@@@%1@@@%2").arg(
                        QString::number(validays),QDateTime::currentDateTime().toString("yyyyMMdd")
                        ));
    QString originalStr120= QStringLiteral("@@@")+machineCode+cusinfo;
    QCryptographicHash sha1(QCryptographicHash::Sha1);
    QByteArray datagram(originalStr120.toLatin1());
    const char* tempConstChar = datagram.data();
    sha1.addData(tempConstChar);
    QString activeCode=sha1.result().toHex();
    QClipboard *board = QApplication::clipboard();
    board->setText(activeCode);//复制至剪贴板
    m_custRegistCode = activeCode;
    return activeCode;
}

void Widget::paintEvent(QPaintEvent */*event*/)
{
    QPainter painter(this);
    QPoint start_point(0, 0);
    QPoint end_point(0, height());

    //QLinearGradient进行渐变色设置
    QLinearGradient linear_gradient(start_point, end_point);
    if(m_currentBGColor.compare(COLORCustumYellow) == 0){
        linear_gradient.setColorAt(0, QColor(253, 253, 202, 255));
        linear_gradient.setColorAt(0.5, QColor(253, 251, 182, 255));
        linear_gradient.setColorAt(1, QColor(252, 249, 164, 255));
    }
    else if(m_currentBGColor.compare(COLORCustumBlue) == 0){
        linear_gradient.setColorAt(0, QColor(215, 242, 250, 255));
        linear_gradient.setColorAt(0.5, QColor(199, 230, 247, 255));
        linear_gradient.setColorAt(1, QColor(186, 220, 244, 255));
    }
    else if(m_currentBGColor.compare(COLORCustumGreen) == 0){
        linear_gradient.setColorAt(0, QColor(208, 253, 202, 255));
        linear_gradient.setColorAt(0.5, QColor(194, 243, 189, 255));
        linear_gradient.setColorAt(1, QColor(179, 233, 176, 255));
    }
    else if(m_currentBGColor.compare(COLORCustumPurple) == 0){
        linear_gradient.setColorAt(0, QColor(220, 215, 254, 255));
        linear_gradient.setColorAt(0.5, QColor(209, 199, 254, 255));
        linear_gradient.setColorAt(1, QColor(199, 186, 254, 255));
    }
    else if(m_currentBGColor.compare(COLORCustumPink) == 0){
        linear_gradient.setColorAt(0, QColor(244, 207, 244, 255));
        linear_gradient.setColorAt(0.5, QColor(239, 190, 239, 255));
        linear_gradient.setColorAt(1, QColor(235, 176, 235, 255));
    }

//    painter.setPen(QPen(QBrush(QColor(140, 140, 140, 120)), 2));
//    painter.fillRect(this->rect(), QBrush(linear_gradient));
    painter.fillRect(this->rect(), QBrush(QColor(109,75,110)));
    painter.setCompositionMode(QPainter::CompositionMode_SourceIn);
    painter.setPen(QColor(199, 186, 254));
    painter.drawRect(this->rect());
    painter.end();
}


QString Widget::getWMIHWInfo(int type){
    /*
//0.当前原生网卡地址：
SELECT MACAddress FROM Win32_NetworkAdapter WHERE (MACAddress IS NOT NULL) AND (NOT (PNPDeviceID LIKE 'ROOT%'))
// 1.硬盘序列号
SELECT PNPDeviceID FROM Win32_DiskDrive WHERE(SerialNumber IS NOT NULL) AND (MediaType LIKE 'Fixed hard disk%')
//2.获取主板序列号
SELECT SerialNumber FROM Win32_BaseBoard WHERE (SerialNumber IS NOT NULL)
// 3.处理器ID
SELECT ProcessorId FROM Win32_Processor WHERE (ProcessorId IS NOT NULL)
// 4.BIOS序列号
SELECT SerialNumber FROM Win32_BIOS WHERE (SerialNumber IS NOT NULL)
// 5.主板型号
SELECT Product FROM Win32_BaseBoard WHERE (Product IS NOT NULL)*/
    QString hwInfo=tr("");
    QStringList sqlCmd;
    sqlCmd.clear();
    sqlCmd<<tr("SELECT MACAddress FROM Win32_NetworkAdapter WHERE (MACAddress IS NOT NULL) AND (NOT (PNPDeviceID LIKE 'ROOT%'))");
    //注意qt调用 wmi时，对查询语句要求很严格，所以 like之类的句子务必精确才能有结果出来
    sqlCmd<<tr("SELECT PNPDeviceID FROM Win32_DiskDrive WHERE( PNPDeviceID IS NOT NULL) AND (MediaType LIKE 'Fixed%')");
    sqlCmd<<tr("SELECT SerialNumber FROM Win32_BaseBoard WHERE (SerialNumber IS NOT NULL)");
    sqlCmd<<tr("SELECT ProcessorId FROM Win32_Processor WHERE (ProcessorId IS NOT NULL)");
    sqlCmd<<tr("SELECT SerialNumber FROM Win32_BIOS WHERE (SerialNumber IS NOT NULL)");
    sqlCmd<<tr("SELECT Product FROM Win32_BaseBoard WHERE (Product IS NOT NULL)");
    QStringList columnName;
    columnName.clear();
    columnName<<tr("MACAddress");
    columnName<<tr("PNPDeviceID");
    columnName<<tr("SerialNumber");
    columnName<<tr("ProcessorId");
    columnName<<tr("SerialNumber");
    columnName<<tr("Product");
    QAxObject *objIWbemLocator = new QAxObject("WbemScripting.SWbemLocator");
    QAxObject *objWMIService = objIWbemLocator->querySubObject("ConnectServer(QString&,QString&)",QString("."),QString("root\\cimv2"));
    QString query=tr("");
    if(type<sqlCmd.size())
        query=sqlCmd.at(type);
    QAxObject *objInterList = objWMIService->querySubObject("ExecQuery(QString&))", query);
    QAxObject *enum1 = objInterList->querySubObject("_NewEnum");
    //需要 include windows.h
    IEnumVARIANT* enumInterface = 0;
    qDebug()<<QUuid((GUID)IID_IEnumVARIANT);
    enum1->queryInterface(QUuid((GUID)IID_IEnumVARIANT), (void**)&enumInterface);
    enumInterface->Reset();
    for (int i = 0; i < objInterList->dynamicCall("Count").toInt(); i++) {
        VARIANT *theItem = (VARIANT*)malloc(sizeof(VARIANT));
        if (enumInterface->Next(1,theItem,NULL) != S_FALSE){
            QAxObject *item = new QAxObject((IUnknown *)theItem->punkVal);
            if(item){
                if(type<columnName.size()){
                    QByteArray datagram(columnName.at(type).toLatin1()); //Or
                    const char* tempConstChar = datagram.data();
                    qDebug()<<"the query is "<<query<<" and cn is "<<QString::fromLatin1(tempConstChar);
                    hwInfo=item->dynamicCall(tempConstChar).toString();
                }
                qDebug() <<" string is "<<hwInfo;
            }else{
                qDebug() <<" item is null";
            }
        }else{
            qDebug() <<" item is false";
        }
    }
    return hwInfo;
}
